﻿using System;
using System.IO;
using System.Numerics;
#if BIG_DECIMAL
using ExtendedNumerics;

namespace LS.Editor.DataTableTools
{
    public sealed partial class DataTableProcessor
    {
        private sealed class BigDecimalProcessor : GenericDataProcessor<BigDecimal>
        {
            public override bool IsSystem
            {
                get
                {
                    return true;
                }
            }

            public override string LanguageKeyword
            {
                get
                {
                    return "ExtendedNumerics.BigDecimal";
                }
            }

            public override string[] GetTypeStrings()
            {
                return new string[]
                {
                    "bigfloat",
                    "bigdecimal",
                    "extendednumerics.bigdecimal"
                };
            }

            public override BigDecimal Parse(string value)
            {
                if (string.IsNullOrEmpty(value))
                {
                    return default;
                }
                return BigDecimal.Parse(value);
            }

            public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
            {
                BigDecimal val = Parse(value);
                binaryWriter.Write(val.Exponent);
                binaryWriter.Write(val.Mantissa.ToByteArray());
            }
        }
        private sealed class BigDecimalArrayProcessor : GenericDataArrayProcessor<BigDecimal>
        {
            public override bool IsSystem
            {
                get
                {
                    return false;
                }
            }

            public override string LanguageKeyword
            {
                get
                {
                    return "ExtendedNumerics.BigDecimal[]";
                }
            }

            public override string[] GetTypeStrings()
            {
                return new string[]
                {
                    "bigfloat[]",
                    "bigdecimal[]",
                    "extendednumerics.bigdecimal[]"
                };
            }

            public override BigDecimal ParseItem(string value)
            {
                if (string.IsNullOrEmpty(value))
                {
                    return default;
                }
                return BigDecimal.Parse(value);
            }

            public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
            {
                var array = Parse(value);
                binaryWriter.Write(array.Length);
                for (int i = 0; i < array.Length; i++)
                {
                    binaryWriter.Write(array[i].Exponent);
                    binaryWriter.Write(array[i].Mantissa.ToByteArray());
                }
            }
        }
        private sealed class BigDecimalListProcessor : GenericDataListProcessor<BigDecimal>
        {
            public override bool IsSystem
            {
                get
                {
                    return false;
                }
            }

            public override string LanguageKeyword
            {
                get
                {
                    return "List<ExtendedNumerics.BigDecimal>";
                }
            }

            public override string[] GetTypeStrings()
            {
                return new string[]
                {
                    "list<bigfloat>",
                    "list<bigdecimal>",
                    "system.collections.generic.list<bigfloat>",
                    "system.collections.generic.list<bigdecimal>",
                };
            }

            public override BigDecimal ParseItem(string value)
            {
                if (string.IsNullOrEmpty(value))
                {
                    return default;
                }
                return BigDecimal.Parse(value);
            }

            public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
            {
                var array = Parse(value);
                binaryWriter.Write(array.Count);
                for (int i = 0; i < array.Count; i++)
                {
                    binaryWriter.Write(array[i].Exponent);
                    binaryWriter.Write(array[i].Mantissa.ToByteArray());
                }
            }
        }

        private sealed class BigDecimalDictionaryProcessor : GenericDataDictionaryProcessor<BigDecimal>
        {
            public override bool IsSystem
            {
                get
                {
                    return false;
                }
            }

            public override string LanguageKeyword
            {
                get
                {
                    return "Dictionary<string,ExtendedNumerics.BigDecimal>";
                }
            }

            public override string[] GetTypeStrings()
            {
                return new string[]
                {
                    "dictionary<string,bigfloat>",
                    "dictionary<string,bigdecimal>",
                };
            }

            public override BigDecimal ParseItem(string value)
            {
                if (string.IsNullOrEmpty(value))
                {
                    return default;
                }
                return BigDecimal.Parse(value);
            }

            public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
            {
                var dic = Parse(value);
                binaryWriter.Write(dic.Count);
                foreach (var item in dic)
                {
                    binaryWriter.Write(item.Key);
                    binaryWriter.Write(item.Value.Exponent);
                    binaryWriter.Write(item.Value.Mantissa.ToByteArray());
                }
            }
        }
    }
}
#endif